﻿/*
寻找素数对 
Time Limit:1000MS  Memory Limit:32768K
  
Description:
哥德巴赫猜想大家都知道一点吧。
我们现在不是想证明这个结论，而是想在程序语言内部能够表示的数集中，
任意取出一个偶数，来寻找两个素数，使得其和等于该偶数。
做好了这件实事，就能说明这个猜想是成立的。
由于可以有不同的素数对来表示同一个偶数，所以专门要求所寻找的素数对是两个值最相近的。 

Input:
输入中是一些偶整数M（6≤M≤10000），0表示结束。 
Output:
对于每个偶数，输出两个彼此最接近的素数，其和等于该偶数。 
Sample Input:
20 30 40
Sample Output:
7 13
13 17
17 23
*/
/*
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Primes
{
public:
	//ctor
	Primes(unsigned num):_num(num), a(2u), b(2u)
	{
		_primes.push_back(2);
		_primes.push_back(3);
		_primes.push_back(5);	
	}
	//取质数集合，最大质数不大于num
	unsigned calPrime(unsigned num);
	inline void getPrimes()const;
	void output()
	{
		copy(_primes.begin(), _primes.end(), ostream_iterator<unsigned>(cout, " "));
	}
private:
	//field
	unsigned a, b;
	unsigned _num;
	vector<unsigned> _primes;
};

void Primes::getPrimes()const
{
	

}
unsigned Primes::calPrime(unsigned num)
{
	unsigned gap=2u;
	unsigned maybePrime=_primes[_primes.size()-1];

	if (maybePrime>num)
		return _primes.size();
	while (1)
	{
		int isPrime=1u;	
		unsigned i=0u;
		maybePrime+=gap;
		gap=6u-gap;
	
		for (i=1; _primes[i]*_primes[i+1]<=maybePrime&& isPrime; ++i )	
			{
				isPrime=maybePrime%_primes[i];
			}
		if (isPrime)
		{
			if (maybePrime>num)
				break;
			_primes.push_back(maybePrime);
		}
	}
	return _primes.size();
}
int main()
{
	unsigned m;
	while(cin>>m&&(6u<=m&&m<=10000u))
	{
		Primes primes(m);

	}
	return 0;
}
*/

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
	vector<int> v;
	for (int num; cin>>num && num; v.push_back(num));
	int maximum=*max_element(v.begin(), v.end());
	
	vector<int> primes;
	primes.push_back(2);
	primes.push_back(3);
	primes.push_back(5);
	//	int maximum=100;
	
	int integer=5;
	int gap=2;
	while (integer<=maximum)//
	{
		integer+=gap;
		gap=6-gap;
		bool is_prime=true;
		for (int i=2; primes[i]*primes[i]<=integer && is_prime; i++)
			if(0==integer%primes[i])
				is_prime=false;
		if(is_prime)
			primes.push_back(integer);
	}
//	copy(primes.begin(), primes.end(), ostream_iterator<int>(cout, " "));
	
	typedef vector<int>::iterator VII;
	for (VII it=v.begin(); it!=v.end(); ++it)
	{
		VII mid=lower_bound(primes.begin(), primes.end(), (*it)>>1)
			;
		for (VII pt=mid; pt!=primes.end(); ++pt)
		{
			int left=*it-*pt;

			if(left==*pt || binary_search(primes.begin(), mid, left))
			{
				cout<<left<<" "<<(*pt)<<endl;
				break;
			}
			
		}
	}
	return 0;
}